package com.hanxiaozhang.threadbase1ndedition.no5juccommonclass;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * 〈一句话功能简述〉<br>
 * 〈CyclicBarrier 循环栅栏〉
 * <p>
 * 概念：
 * 它可以让一组线程到达一个屏障点的时被阻塞，直到最后一个线程到达屏障点才开启，继续往下执行
 * <p>
 * 常见方法：
 * CyclicBarrier(int parties):构造函数，parties表示屏障需要拦截的线程数量，
 * 每个线程使用await()方法告诉CyclicBarrier我已经到达了屏障，然后当前线程被阻塞；
 * CyclicBarrier(int parties，Runnable barrierAction):构造函数，用于在线程到达屏障时，
 * 优先执行barrierAction线程中的业务代码，方便处理更复杂的业务场景；
 * await():通知CyclicBarrier已经达到屏障，然后当前这个线程被阻塞，一直到所有的线程都到达屏障；
 * await(long timeout, TimeUnit unit)：通知CyclicBarrier已经达到屏障，然后当前这个线程被阻塞，
 * 一直到所有的线程都到达屏障，或者超过指定的等待时间；
 * getParties()：返回参与相互等待的线程数；
 * getNumberWaiting()：返回当前在屏障处等待的参与者数目，此方法主要用于调试和断言；
 * isBroken()：判断此屏障是否处于中断状态，是则返回true；否则返回false；
 * reset()：将屏障重置为其初始状态。
 *
 * @author hanxinghua
 * @create 2021/11/14
 * @since 1.0.0
 */
public class No3CyclicBarrier {

    public static void main(String[] args) {

        //  使用方式一：
        // CyclicBarrier barrier = new CyclicBarrier(20);

        //  使用方式二：
        CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("满人，发车"));

        for (int i = 0; i < 100; i++) {

            new Thread(() -> {
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();

        }
    }
}
